import { isMP4File } from "./../utils/fs";
import * as path from "path";
import * as fse from "fs-extra";
import * as NodeID3 from "node-id3";

import {
	ICache,
	insertCache,
	getCache,
	getCacheItem,
	createAudioLabel,
	createVideoLabel,
	genVitualPath,
} from "../db/cache";
import { info } from "../utils/log";
import { MEDIA_DIR } from "./config";
import { existFilename, existKey, IDataMP3 } from "../db/media";
import { md5FromBuffer, md5FromBuffer2 } from "../utils/md5";
import {
	isMP3File,
	isFile,
	resolveFile,
	formatTitle,
	isMP3Buffer,
	isMP4Buffer,
} from "../utils/fs";
import { debug } from "console";

export const VIRTUAL_PATH_PREFIX = "$DIR";
/**
 *
 * @param file 文件名
 * @param cache 缓存信息
 * @returns 生成 AUDIO 类数据项目
 */
function genAudioDBItem(file: string, cache: ICache[], publicKeys: string[]) {
	const abs = path.resolve(MEDIA_DIR, file);
	const buffer = fse.readFileSync(abs);

	if (!isMP3Buffer(buffer) && isMP4Buffer(buffer)) {
		return genVideoDBItem(file, cache, publicKeys);
	}
	const mp3Tags = NodeID3.read(buffer);
	const virtualPath = genVitualPath(file);

	const dbItem: IDataMP3 = {
		...mp3Tags,
		virtualPath,
		key: "",
		tags: [],
		label: "",
		mediatype: "AUDIO",
	};

	if (!dbItem.title) {
		const basename = path.basename(file);
		const indexOfDot = basename.lastIndexOf(".");
		dbItem.title = basename.slice(0, indexOfDot);
	}

	if (!dbItem.album) {
		dbItem.album = "未知专辑";
	}

	if (!dbItem.artist) {
		dbItem.artist = "未知艺术家";
	}

	const label = createAudioLabel(dbItem);
	const targetCache = getCacheItem(cache, label);

	if (!targetCache.key) {
		const key = md5FromBuffer2(buffer);

		if (publicKeys.includes(key)) {
			return null;
		}

		info(`Adding collection "${label}"`);
		insertCache({ ...targetCache, key });
		dbItem.key = key;
		publicKeys.push(key);
	} else {
		dbItem.key = targetCache.key;
	}

	dbItem.label = label;
	dbItem.tags = targetCache.tags;

	return dbItem;
}

/**
 *
 * @param file 文件名
 * @param cache 缓存信息
 * @returns 生成 VIDEO 类数据项目
 */
function genVideoDBItem(file: string, cache: ICache[], publicKeys: string[]) {
	const abs = path.resolve(MEDIA_DIR, file);
	const buffer = fse.readFileSync(abs);
	const virtualPath = path.join(VIRTUAL_PATH_PREFIX, path.basename(file));

	const dbItem: IDataMP3 = {
		virtualPath,
		key: "",
		tags: [],
		label: "",
		artist: "",
		album: "",
		mediatype: "VIDEO",
	};

	const label = createVideoLabel(dbItem);
	const targetCache = getCacheItem(cache, label);

	if (!targetCache.key) {
		const key = md5FromBuffer2(buffer);

		if (publicKeys.includes(key)) {
			return null;
		}

		info(`Adding collection "${label}"`);
		insertCache({ ...targetCache, key });
		dbItem.key = key;
		publicKeys.push(key);
	} else {
		dbItem.key = targetCache.key;
	}

	dbItem.label = label;
	dbItem.title = formatTitle(file);

	return dbItem;
}

/**
 * 获取所有 MP3 文件数据
 */
export async function provideMediaFiles() {
	const publicKeys = [];
	const cache = await getCache();

	const list = fse
		.readdirSync(MEDIA_DIR)
		.map((file) => resolveFile(file))
		.filter(async (file) => isFile(file) && (await existFilename(file)))
		.map((file) => {
			try {
				if (isMP3File(file)) {
					return genAudioDBItem(file, cache, publicKeys);
				} else if (isMP4File(file)) {
					return genVideoDBItem(file, cache, publicKeys);
				} else {
					return null;
				}
			} catch (e) {
				return null;
			}
		})
		.filter((item) => item !== null);

	return list;
}
